package com.galudisu.ddd

import akka.actor.Props
import akka.cluster.sharding.{ClusterSharding, ClusterShardingSettings}

import scala.reflect.ClassTag

abstract class Aggregate[FO <: EntityFieldsObject[String, FO], E <: PersistentEntity[FO]: ClassTag] extends BasicActor {

  val idExtractor = PersistentEntity.PersistentEntityIdExtractor(context.system)

  val entityShardRegion =
    ClusterSharding(context.system).start(
      typeName = entityName,
      entityProps = entityProps,
      settings = ClusterShardingSettings(context.system),
      extractEntityId = idExtractor.extractEntityId,
      extractShardId = idExtractor.extractShardId)

  def entityProps: Props

  private def entityName = {
    val entityTag = implicitly[ClassTag[E]]
    entityTag.runtimeClass.getSimpleName
  }

  def forwardCommand(command: EntityCommand) =
    entityShardRegion.forward(command)
}
